/*
 * Copyright 2008-2010 Daniel Cachapa <cachapa@gmail.com>
 * 
 * This program is distributed under the terms of the GNU General Public License Version 3
 * The license can be read in its entirety in the LICENSE.txt file accompanying this source code,
 * or at: http://www.gnu.org/copyleft/gpl.html
 * 
 * This file is part of Libra.
 *
 * WeightWatch is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * WeightWatch is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the WeightWatch source code. If not, see: http://www.gnu.org/licenses
 */

package net.cachapa.libra;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Vector;

import net.cachapa.libra.adapter.ValuesAdapter;
import net.cachapa.libra.data.Database;
import net.cachapa.libra.data.Value;
import net.cachapa.libra.util.MyDate;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;

public class DatabaseList extends ListActivity {
	private static final int EDIT_ENTRY = 0;
	private static final int DELETE_ENTRY = 1;
	private static final int MENU_COMPLETE_DATABASE = 2;
	private static final int MENU_EXPORT_DATABASE = 3;
	private static final int MENU_IMPORT_DATABASE = 4;
	private static final int MENU_DELETE_DATABASE = 5;
	private static final int DIALOG_DELETE_DATABASE = 0;
	private static final String CSV_FILENAME = "Libra.csv";
	private int day, month, year;
	
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.databaselist);
		
		getListView().setEmptyView(findViewById(R.id.empty));
		
		Intent databaseIntent = getIntent();
		day = databaseIntent.getIntExtra("day", -1);
		month = databaseIntent.getIntExtra("month", -1);
		year = databaseIntent.getIntExtra("year", -1);
		
		ValuesAdapter valuesAdapter = new ValuesAdapter(this, new Vector<Value>());
		setListAdapter(valuesAdapter);
		
		// Register a menu for the long press
		registerForContextMenu(getListView());
		
		// Show a message to tell people that they can delete entries
		Toast.makeText(this, R.string.long_press_tip, Toast.LENGTH_SHORT).show();
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		updateValues();
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
		Value value = (Value)getListAdapter().getItem(((AdapterContextMenuInfo)menuInfo).position);
		menu.setHeaderTitle(value.toString(this));
		menu.add(0, EDIT_ENTRY, 0, R.string.edit);
		menu.add(0, DELETE_ENTRY, 1, R.string.delete);
		super.onCreateContextMenu(menu, v, menuInfo);
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
		ValuesAdapter valuesAdapter = (ValuesAdapter)getListAdapter();
		Value value = valuesAdapter.getItem(info.position);
		Database database = Database.getInstance(this);
		
		switch (item.getItemId()) {
		case EDIT_ENTRY:
			editItem(value);
			return true;
		case DELETE_ENTRY:
			database.deleteValue(value);
			valuesAdapter.deleteValue(info.position);
			Toast.makeText(this, R.string.value_deleted, Toast.LENGTH_SHORT).show();
			updateValues();
			return true;
		}
		return false;
	}
	
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		Value value = ((ValuesAdapter)getListAdapter()).getItem(position);
		editItem(value);
	}
	
	private void updateValues() {
		MyDate chartDate;
		Vector<Value> values;
		Database database = Database.getInstance(this);
		
		if (day > 0) {
			chartDate = new MyDate(year, month, day);
			values = database.getWeek(chartDate, Database.ORDER_DESC);
			setTitle(String.format(getString(R.string.database_week), chartDate.toMediumString()));
		}
		else if (month > 0) {
			chartDate = new MyDate(year, month, 1);
			values = database.getMonth(chartDate, Database.ORDER_DESC);
			setTitle(String.format(getString(R.string.database_month_year), chartDate.getMonthName(), year));
		}
		else if (year > 0) {
			chartDate = new MyDate(year, 1, 1);
			values = database.getYear(chartDate, Database.ORDER_DESC);
			setTitle(String.format(getString(R.string.database_year), year));
		}
		else {
			values = database.getAllValues(Database.ORDER_DESC);
		}
		
		((ValuesAdapter)getListAdapter()).refreshValues(values);
	}
	
	private void editItem(Value value) {
		Intent editIntent = new Intent(this, net.cachapa.libra.InsertValue.class);
		editIntent.putExtra("year", value.getDate().getYear());
		editIntent.putExtra("month", value.getDate().getMonth());
		editIntent.putExtra("day", value.getDate().getDay());
		editIntent.putExtra("weight", value.getWeight());
		startActivity(editIntent);
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		menu.clear();
		Database database = Database.getInstance(this);
		if (year > 0) {
			menu.add(Menu.NONE, MENU_COMPLETE_DATABASE, 0, R.string.all_entries).setIcon(android.R.drawable.ic_menu_my_calendar);
		}
		else {
			if (!database.isEmpty()) {
				menu.add(Menu.NONE, MENU_EXPORT_DATABASE, 0, R.string.export_database).setIcon(android.R.drawable.ic_menu_upload);
			}
			menu.add(Menu.NONE, MENU_IMPORT_DATABASE, 1, R.string.import_database).setIcon(android.R.drawable.ic_menu_set_as);
			menu.add(Menu.NONE, MENU_DELETE_DATABASE, 2, R.string.delete_database).setIcon(android.R.drawable.ic_menu_delete);
		}
		return super.onCreateOptionsMenu(menu);
	}
	
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case MENU_COMPLETE_DATABASE:
			Intent databaseIntent = new Intent(this, net.cachapa.libra.DatabaseList.class);
			startActivity(databaseIntent);
			break;
		case MENU_EXPORT_DATABASE:
			exportDatabase();
			break;
		case MENU_IMPORT_DATABASE:
			new DatabaseImporter().execute(0);
			break;
		case MENU_DELETE_DATABASE:
			showDialog(DIALOG_DELETE_DATABASE);
			break;
		}
		return false;
	}
	
	private void exportDatabase() {
		Database database = Database.getInstance(this);
		String path = Environment.getExternalStorageDirectory() + "/" + CSV_FILENAME;
		try {
			database.exportToFile(path);
		} catch (IOException e) {
			Toast.makeText(this, "Error: " + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
			e.printStackTrace();
			return;
		}
		Toast.makeText(this, "Database exported to " + path, Toast.LENGTH_LONG).show();
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DIALOG_DELETE_DATABASE:
			return new AlertDialog.Builder(this)
			.setIcon(android.R.drawable.ic_dialog_alert)
			.setTitle(R.string.confirmation_title)
			.setMessage(R.string.confirmation_msg)
			.setPositiveButton(R.string.boom, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int whichButton) {
					Database database = Database.getInstance(getBaseContext());
					database.deleteDatabase();
					((ValuesAdapter)getListAdapter()).deleteAllValues();
					Toast.makeText(getBaseContext(), R.string.database_deleted, Toast.LENGTH_SHORT).show();
				}
			})
			.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int whichButton) {
					Toast.makeText(getBaseContext(), R.string.database_rescued, Toast.LENGTH_SHORT).show();
				}
			})
			.create();
		}
		return null;
	}
	
	
	
	
	private class DatabaseImporter extends AsyncTask<Integer, Integer, String> {
		private ProgressDialog progressDialog;
		@Override
		protected void onPreExecute() {
			progressDialog = ProgressDialog.show(DatabaseList.this, null, getString(R.string.importing_database), true);
		}
		
		protected String doInBackground(Integer... params) {
			Database database = Database.getInstance(DatabaseList.this);
			String path = Environment.getExternalStorageDirectory() + "/" + CSV_FILENAME;
			int imported = 0;
			String result;
			try {
				imported = database.importFromFile(path);
			} catch (FileNotFoundException e) {
				result = "Error: " + e.getLocalizedMessage();
				e.printStackTrace();
				return result;
			} catch (IllegalArgumentException e) {
				return e.getMessage();
			}
			switch (imported) {
			case 0:
				result = getString(R.string.import_complete_nothing);
				break;
			case 1:
				result = getString(R.string.import_complete_one);
				break;
			default:
				result = String.format(getString(R.string.import_complete_many), imported);
				break;
			}
			return result;
		}
		
		protected void onPostExecute(String message) {
			progressDialog.dismiss();
			Toast.makeText(DatabaseList.this, message, Toast.LENGTH_LONG).show();
			Database database = Database.getInstance(DatabaseList.this);
			Vector<Value> values = database.getAllValues(Database.ORDER_DESC);
			((ValuesAdapter)getListAdapter()).refreshValues(values);
		}
	}
}